#include <bits/stdc++.h>
using namespace std;

int rows, cols, n, k;
int maxST[2022][2022][12], minST[2022][2022][12];
int logk;

inline int queryMax(int x1, int y1, int x2, int y2) {
  int topLeft = maxST[x1][y1][logk];
  int topRight = maxST[x1][y2 - (1 << logk) + 1][logk];
  int bottomLeft = maxST[x2 - (1 << logk) + 1][y1][logk];
  int bottomRight = maxST[x2 - (1 << logk) + 1]
                         [y2 - (1 << logk) + 1][logk];
  return max({topLeft, topRight, bottomLeft, bottomRight});
}

inline int queryMin(int x1, int y1, int x2, int y2) {
  int topLeft = minST[x1][y1][logk];
  int topRight = minST[x1][y2 - (1 << logk) + 1][logk];
  int bottomLeft = minST[x2 - (1 << logk) + 1][y1][logk];
  int bottomRight = minST[x2 - (1 << logk) + 1]
                         [y2 - (1 << logk) + 1][logk];
  return min({topLeft, topRight, bottomLeft, bottomRight});
}

int main() {
  cin >> n >> k;
  rows = cols = n;

  // 初始化输入数据
  for (int i = 1; i <= rows; ++i) {
    for (int j = 1; j <= cols; ++j) {
      int value;
      scanf("%d", &value);
      maxST[i][j][0] = minST[i][j][0] = value;
    }
  }

  // 构建稀疏表
  for (int level = 1; level <= 12; ++level) {
    int step = 1 << (level - 1);
    for (int i = 1; i + step <= rows; ++i) {
      for (int j = 1; j + step <= cols; ++j) {
        maxST[i][j][level] =
            max({maxST[i][j][level - 1], maxST[i + step][j][level - 1],
                 maxST[i][j + step][level - 1],
                 maxST[i + step][j + step][level - 1]});

        minST[i][j][level] =
            min({minST[i][j][level - 1], minST[i + step][j][level - 1],
                 minST[i][j + step][level - 1],
                 minST[i + step][j + step][level - 1]});
      }
    }
  }

  logk = static_cast<int>(log2(k));

  // 输出结果
  for (int i = 1; i <= rows - k + 1; ++i) {
    for (int j = 1; j <= cols - k + 1; ++j) {
      printf("%d ", queryMax(i, j, i + k - 1, j + k - 1));
    }
    printf("\n");
  }

  return 0;
}
